package com.bootdo.shop.controller;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.bootdo.common.annotation.Log;
import com.bootdo.common.config.BootdoConfig;
import com.bootdo.common.controller.BaseController;
import com.bootdo.common.utils.FileUtil;
import com.bootdo.common.utils.IPUtils;
import com.bootdo.common.utils.MD5Utils;
import com.bootdo.common.utils.PageUtils;
import com.bootdo.common.utils.QRCodeUtil;
import com.bootdo.common.utils.R;
import com.bootdo.hjh.domain.ErrorConstant;
import com.bootdo.hjh.domain.UserAddress;
import com.bootdo.hjh.ex.ThrowUtils;
import com.bootdo.hjh.pay.AlipayService;
import com.bootdo.hjh.service.OrderService;
import com.bootdo.hjh.service.PointsService;
import com.bootdo.hjh.service.UserAddressService;
import com.bootdo.hjh.service.WxPayService;
import com.bootdo.shop.domain.Calculating;
import com.bootdo.shop.domain.Category;
import com.bootdo.shop.domain.GoodsCategory;
import com.bootdo.shop.domain.GoodsConstant;
import com.bootdo.shop.domain.GoodsImage;
import com.bootdo.shop.domain.GoodsLimit;
import com.bootdo.shop.domain.OrderDetail;
import com.bootdo.shop.domain.OrderInfo;
import com.bootdo.shop.domain.request.GoodsReq;
import com.bootdo.shop.domain.request.OrderInfoReq;
import com.bootdo.shop.domain.request.ShoppingCartReq;
import com.bootdo.shop.domain.response.GoodsRes;
import com.bootdo.shop.domain.response.OrderInfoRes;
import com.bootdo.shop.domain.response.ShoppingCartRes;
import com.bootdo.shop.service.GoodsService;
import com.bootdo.shop.service.ShopOrderService;
import com.bootdo.shop.service.ShoppingCartService;
import com.bootdo.system.domain.UserDO;
import com.bootdo.system.service.UserService;

@Controller
@RequestMapping(value="/shop")
public class ShopController extends BaseController {
	private static final Logger logger = LoggerFactory.getLogger(ShopController.class);
	@Autowired
	private GoodsService goodsService;
	@Autowired
	private ShopOrderService shopOrderService;
	@Autowired
	private ShoppingCartService shoppingCartService;
	@Autowired
	private UserAddressService userAddressService;
	@Autowired
	private BootdoConfig bootdoConfig;
	@Autowired
	private AlipayService alipayService;
	@Autowired
	private WxPayService wxPayService;
	
	@Autowired
	private UserService userService;
	
	@Autowired
	private OrderService orderService;
	
	@Autowired
	private PointsService pointsService;
	
	@GetMapping("/home")
	public String index(Model model) {
		UserDO userDo = getUser();
		List<Category> categoryList = goodsService.categoryList();
		for(Category category : categoryList) {
			GoodsReq goodsReq = new GoodsReq();
			goodsReq.setCategoryId(category.getId());
			//已经上架的商品
			goodsReq.setIsOnsale(GoodsConstant.GOODS_ONSALE_STATUS_PUTAWAY.getStatus());
			goodsReq.setLimit(20);
			goodsReq.setMemberLevel(userDo.getMemberLevel());
			goodsReq.setAgentLevel(userDo.getAgentLevel());
			List<GoodsRes> goodsList = goodsService.goodsList(goodsReq);
			goodsService.coverPriceForGoods(userDo.getMemberLevel(), userDo.getAgentLevel(), goodsList);
			category.setGoodsList(goodsList);
		}
		model.addAttribute("categoryList", categoryList);
		return "shop/index";
	}
	
	@GetMapping("/shopping_cart/total_number")
	@ResponseBody
	public R shoppingCartNum() {
		Long userId = getUserId();
		ShoppingCartReq shoppingCartReq = new ShoppingCartReq();
		shoppingCartReq.setUserId(userId);
		Integer shoppingCartNum = 0;
		shoppingCartNum = shoppingCartService.getShoppingCartNum(shoppingCartReq);
		return R.ok(shoppingCartNum.toString());
	}
	
	@GetMapping("/shopping_cart")
	public String shoppingCart(Model model) {
		UserDO userDO = getUser();
		List<Category> categoryList = goodsService.categoryList();
		model.addAttribute("categoryList", categoryList);
		ShoppingCartReq shoppingCartReq = new ShoppingCartReq();
		shoppingCartReq.setUserId(userDO.getUserId());
		shoppingCartReq.setMemberLevel(userDO.getMemberLevel());
		shoppingCartReq.setAgentLevel(userDO.getAgentLevel());
		List<ShoppingCartRes> list = shoppingCartService.getShoppingCartList(shoppingCartReq);
		Calculating calculating = shopOrderService.calculatingPrice(list, userDO);
		model.addAttribute("list", list);
		model.addAttribute("calculating", calculating);
		List<UserAddress> userAddressList = userAddressService.getUserAddressAll(userDO.getUserId());
		model.addAttribute("userAddressList", userAddressList);
		return "shop/shopping_cart";
	}
	
	@GetMapping("/calculating")
	@ResponseBody
	public R calculating() {
		UserDO userDO = getUser();
		ShoppingCartReq shoppingCartReq = new ShoppingCartReq();
		shoppingCartReq.setUserId(userDO.getUserId());
		shoppingCartReq.setMemberLevel(userDO.getMemberLevel());
		shoppingCartReq.setAgentLevel(userDO.getAgentLevel());
		List<ShoppingCartRes> list = shoppingCartService.getShoppingCartList(shoppingCartReq);
		Calculating calculating = shopOrderService.calculatingPrice(list, userDO);
		return R.ok().put("calculating", calculating);
	}
	
	@PostMapping("/shopping_cart/add")
	@ResponseBody
	public R<?> shoppingCartAdd(@RequestBody ShoppingCartReq shoppingCartReq) {
		Long userId = getUserId();
		shoppingCartReq.setUserId(userId);
		if(shoppingCartReq.getGoodsNum() == null) {
			shoppingCartReq.setGoodsNum(1);
		}
		ShoppingCartReq  scq  = shoppingCartService.addShoppingCart(shoppingCartReq);
		return R.ok().put("domain", scq);
	}
	
	@PostMapping("/shopping_cart/delete")
	@ResponseBody
	public R<?> shoppingCartDelete(@RequestBody ShoppingCartReq shoppingCartReq) {
		Long userId = getUserId();
		shoppingCartReq.setUserId(userId);
		shoppingCartService.deleteShoppingCart(shoppingCartReq);
		Integer shoppingCartNum = 0;
		shoppingCartNum = shoppingCartService.getShoppingCartNum(shoppingCartReq);
		return R.ok(shoppingCartNum.toString());
	}
	
	@GetMapping("/category/{id}")
	public String shoppingCart(@PathVariable("id") Integer id,Model model) {
		UserDO userDO = getUser();
		GoodsReq goodsReq = new GoodsReq();
		goodsReq.setCategoryId(id);
		goodsReq.setLimit(null);
		goodsReq.setMemberLevel(userDO.getMemberLevel());
		goodsReq.setAgentLevel(userDO.getAgentLevel());
		goodsReq.setIsOnsale(GoodsConstant.GOODS_ONSALE_STATUS_PUTAWAY.getStatus());
		List<GoodsRes> goodsList = goodsService.goodsList(goodsReq);
		model.addAttribute("goodsList", goodsList);
		List<Category> categoryList = goodsService.categoryList();
		model.addAttribute("categoryList", categoryList);
		Category category = goodsService.getCategoryById(id);
		model.addAttribute("category", category);
		return "shop/category";
	}
	
	@GetMapping("/detail/{id}")
	public String detail(@PathVariable("id") Integer id,Model model) {
		UserDO userDO = getUser();
		List<Category> categoryList = goodsService.categoryList();
		model.addAttribute("categoryList", categoryList);
		GoodsReq goodReq = new GoodsReq();
		goodReq.setId(id);
		goodReq.setMemberLevel(userDO.getMemberLevel());
		goodReq.setAgentLevel(userDO.getAgentLevel());
		GoodsRes goodsRes = goodsService.goodsDetail(goodReq);
		model.addAttribute("goods", goodsRes);
		return "shop/detail";
	}
	
	@GetMapping("/order/list")
	public String orderList(Model model) {
		List<Category> categoryList = goodsService.categoryList();
		model.addAttribute("categoryList", categoryList);
		UserDO userDO = getUser();
		OrderInfoReq orderInfoReq = new OrderInfoReq();
		orderInfoReq.setUserId(userDO.getUserId());
		orderInfoReq.setStart(null);
		List<OrderInfoRes> list = shopOrderService.userOrderList(orderInfoReq);
		logger.info("orderList : {}",JSON.toJSONString(list));
		model.addAttribute("orderList", list);
		return "shop/order_list";
	}
	
	
	@PostMapping("/order/create")
	@ResponseBody
	public R<?> createOrder(@RequestBody ShoppingCartReq shoppingCartReq,Model model,HttpServletRequest request)   {
		UserDO userDO = getUser();
		shoppingCartReq.setUserId(userDO.getUserId());
		shoppingCartReq.setMemberLevel(userDO.getMemberLevel());
		shoppingCartReq.setAgentLevel(userDO.getAgentLevel());
		List<ShoppingCartRes> list = shoppingCartService.getShoppingCartList(shoppingCartReq);
		OrderInfoReq orderInfoReq = new OrderInfoReq();
		orderInfoReq.setUserId(userDO.getUserId());
		orderInfoReq.setUserAddressId(shoppingCartReq.getUserAddressId());
		orderInfoReq.setSource("web");
		orderInfoReq.setPayType(shoppingCartReq.getPayType());
		List<OrderDetail> orderDetailList = new ArrayList<>();
		for(ShoppingCartRes shoppingCartRes : list) {
			OrderDetail orderDetail = new OrderDetail();
			orderDetail.setType(1);
			orderDetail.setGoodsNumber(shoppingCartRes.getGoodsNum());
			orderDetail.setGoodsId(shoppingCartRes.getGoodsId());
			orderDetailList.add(orderDetail);
		}
		orderInfoReq.setOrderDetails(orderDetailList);
		OrderInfoRes orderInfoRes = shopOrderService.createOrder(orderInfoReq);
		return R.ok().put("orderInfo", orderInfoRes);
	}
	
	@GetMapping("/order/pay/alipay")
	@ResponseBody
	public String orderAliapy(Integer id,Model model,HttpServletRequest request)  {
		OrderInfo orderInfo = shopOrderService.getOrderInfoById(id);
		if(orderInfo == null) {
			ThrowUtils.throwException(ErrorConstant.PARAM_ERROR.getErrorCode(), "订单不存在");
		}
		Float amount = orderInfo.getTotalPayee() / 100f;
	    BigDecimal b = new  BigDecimal(amount);  
	    Float f1 = b.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();
		String result = alipayService.pay(orderInfo.getOrderNo(), 
        		String.valueOf(f1),
        		orderInfo.getOrderTitle(), 
        		orderInfo.getOrderTitle(),"http://www.meixiberry.com/shop/order/list");
		return "<html>".concat(result).concat("</html>");
	}
	
	@GetMapping("/order/pay/wx")
	public String orderWx(Integer id,Model model,HttpServletRequest request)  {
		List<Category> categoryList = goodsService.categoryList();
		model.addAttribute("categoryList", categoryList);
		//获取当前用户
		OrderInfo orderInfo = shopOrderService.getOrderInfoById(id);
		model.addAttribute("orderId", id);
		if(orderInfo == null) {
			ThrowUtils.throwException(ErrorConstant.PARAM_ERROR.getErrorCode(), "订单不存在");
		}
		try {
			Map<String, String> r = wxPayService.doPay(orderInfo.getOrderTitle(), orderInfo.getOrderNo(), orderInfo.getTotalPayee().toString(), IPUtils.getIpAddr(request), orderInfo.getId().toString());
	        String path = "";
            if(null != r.get("err_code") && r.get("err_code").toString().equals("ORDERPAID")) {
	        		/**订单已支付**/	
            		model.addAttribute("msg", "该订单已支付");
	        }
            String codeUrl = r.get("code_url").toString();
            String destPath = "/mnt/hjh/wx/qrcode/";
            path = QRCodeUtil.encode(codeUrl, destPath);
            model.addAttribute("path", "wx/qrcode/"+path);
        } catch (Exception e) {
        		ThrowUtils.throwException(ErrorConstant.PARAM_ERROR.getErrorCode(), "服务器出错了");
        }
        return "shop/wx_pay";
	}
	
	@GetMapping("/order/pay/jifen")
	public String orderJifen(Integer id,Model model,HttpServletRequest request)  {
		List<Category> categoryList = goodsService.categoryList();
		model.addAttribute("categoryList", categoryList);
		//获取当前用户
		OrderInfo orderInfo = shopOrderService.getOrderInfoById(id);
		if(orderInfo == null) {
			ThrowUtils.throwException(ErrorConstant.PARAM_ERROR.getErrorCode(), "订单不存在");
		}
        model.addAttribute("orderInfo", orderInfo);
        UserDO userDO = getUser();
        Integer cashPointsTotal = pointsService.cashPointsTotal(userDO.getUserId());
        String cashPointBalanceStr = "0.00";
        if(cashPointsTotal!=null){
            cashPointBalanceStr = new java.text.DecimalFormat("#.00").format(cashPointsTotal/100.0);
        }
        model.addAttribute("cashPointBalance",cashPointsTotal);
        model.addAttribute("cashPointBalanceStr",cashPointBalanceStr);
        
        return "shop/jifen_pay";
	}
	
	@Log("订单使用现金积分支付")
    @PostMapping("/cash_pay")
    @ResponseBody
    public R cashPay(Model model,@RequestBody Map<String,String> param ){
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //{"orderId":orderId,"payPwd":payPwd};
        Integer orderId = null;
        String payPwd = null;
        payPwd = param.get("payPwd");
        UserDO userDO = getUser();
        ThrowUtils.throwCondition(StringUtils.isBlank(param.get("orderId")),100,"订单ID不能为空");
        ThrowUtils.throwCondition(StringUtils.isBlank(payPwd),100,"支付密码不能为空");
        //校验交易密码
        UserDO user = userService.get(userDO.getUserId());
        ThrowUtils.throwCondition(StringUtils.isBlank(user.getPayPwd()),100,"您还没有设置交易密码,请到个人中心设置交易密码");
        String currPayPwd = MD5Utils.encrypt(payPwd);
        ThrowUtils.throwCondition(!user.getPayPwd().equals(currPayPwd),100,"交易密码错误");

        orderId = Integer.valueOf(param.get("orderId"));
        OrderInfo orderInfo = shopOrderService.getOrderInfoById(orderId);
        ThrowUtils.throwCondition(orderInfo==null,100,"订单不存在");
        ThrowUtils.throwCondition(orderInfo.getPayStatus() == 1,100,"订单已经支付，请不要重复操作");
        //去支付
        orderService.shopCashPay(userDO, orderInfo);
        return R.ok();
    }
	
	
	
	@GetMapping("/system/goods_category/manager")
	public String sysGoodsCategoryManager() {
		
		return "shop/system/goods_category";
	}
	
	@GetMapping("/system/goods_category/list")
	@ResponseBody
	public PageUtils sysGoodsCategoryList() {
		List<Category> list = goodsService.categoryListByManager();
        PageUtils pageUtils = new PageUtils(list, list.size());
        return pageUtils;
	}
	
	@PostMapping("/system/category/modify")
	@ResponseBody
	public R<?> sysModifyCategory(@RequestBody Category category) {
		if(category.getId() == null || category.getId() == 0) {
			goodsService.addCategory(category);
		}else {
			goodsService.modifyCategory(category);
		}
		return R.ok();
	}
	
	@GetMapping("/system/goods/manager")
	public String sysGoodsManager(Model model) {
		List<Category> categoryList = goodsService.categoryList();
		model.addAttribute("categoryList", categoryList);
		return "shop/system/goods";
	}
	
	@GetMapping("/order/detail/{orderId}")
	@ResponseBody
	public R orderDetail(@PathVariable("orderId") Integer orderId) {
		OrderInfoReq orderInfoReq = new OrderInfoReq();
		orderInfoReq.setId(orderId);
		OrderInfoRes orderInfoRes = shopOrderService.orderDetail(orderInfoReq);
		return R.ok().put("order", orderInfoRes);
	}
	
	@PostMapping("/order/consignment")
	@ResponseBody
	public R consignment(@RequestBody OrderInfoReq orderInfoReq) {
		shopOrderService.consignment(orderInfoReq);
		return R.ok();
	}
	
	
	@GetMapping("/system/goods/list")
	@ResponseBody
	public PageUtils sysGoodsList(GoodsReq goodsReq) {
		List<GoodsRes> list = goodsService.goodsList(goodsReq);
		Integer total = goodsService.goodsListCount(goodsReq);
        PageUtils pageUtils = new PageUtils(list,total);
        return pageUtils;
	}
	
	@GetMapping("/system/goods/add")
	public String sysGoodsManager(@RequestParam(value="id",required=false) Integer id,Model model) {
		List<Category> categoryList = goodsService.categoryList();
		GoodsRes goodsRes = new GoodsRes();
		if(id != null && id > 0) {
			goodsRes = goodsService.getGoodsDetailById(id);
			model.addAttribute("goods", goodsRes);
			List<GoodsCategory> goodsCategories = goodsService.getCategoryByGoodsId(id);
			for(Category category : categoryList) {
				for(GoodsCategory  goodsCategory : goodsCategories) {
					if(category.getId().intValue() == goodsCategory.getCategoryId()) {
						category.setIsChecked(1);
					}
				}
			}
			List<GoodsLimit> goodsLimitList = goodsService.getGoodsLimit(id);
			model.addAttribute("goodsLimitList", goodsLimitList);
		}
		model.addAttribute("goods", goodsRes);
		model.addAttribute("categoryList", categoryList);
		return "shop/system/addGoods";
	}
	
	@PostMapping("/system/goods/save")
	@ResponseBody
	public R saveGoods(GoodsReq goodsReq,
			HttpServletRequest request) throws IOException, Exception {
		if(goodsReq.getThumbnailImageFile() != null) {
			String thumbnailImageFileName = goodsReq.getThumbnailImageFile().getOriginalFilename();
			if(null != thumbnailImageFileName && !thumbnailImageFileName.equals("")) {
				thumbnailImageFileName = FileUtil.renameToUUID(thumbnailImageFileName);
				FileUtil.uploadFile(goodsReq.getThumbnailImageFile().getBytes(), bootdoConfig.getUploadPath(), thumbnailImageFileName);
				goodsReq.setThumbnailImage(thumbnailImageFileName);
			}
		}
		if(goodsReq.getImageLargeFile().length > 0) {
			if(goodsReq.getGoodsImageList() == null) {
				goodsReq.setGoodsImageList(new ArrayList<>());
			}
			for(int i = 0;i< goodsReq.getImageLargeFile().length;i++ ) {
				MultipartFile file = goodsReq.getImageLargeFile()[i];
				String fileName = file.getOriginalFilename();
				if(fileName != null && !fileName.equals("")) {
					fileName = FileUtil.renameToUUID(fileName);
					FileUtil.uploadFile(file.getBytes(), bootdoConfig.getUploadPath(), fileName);
					GoodsImage gi = new GoodsImage();
					gi.setImageLarge(fileName);
					gi.setSortOrder(i);
					goodsReq.getGoodsImageList().add(gi);
				}
			}
		}
		
		if(goodsReq.getId() != null) {
			goodsService.updateGoods(goodsReq);
		}else {
			goodsService.addGoods(goodsReq);
		}
		return R.ok();
	}
	
	@PostMapping("/system/goods/delete_image")
	@ResponseBody
	public R<?> deleteImage(@RequestBody GoodsImage goodsImage)  {
		goodsService.deleteImage(goodsImage);
		return R.ok();
	}
	
	
	@GetMapping("/system/order/manager")
	public String orderManager()  {
		return "/shop/system/order_manager";
	}
	
	@GetMapping("/system/order/list")
	@ResponseBody
	public PageUtils systemOrderList(OrderInfoReq orderInfoReq)  {
		if(orderInfoReq.getUserId() == null) {
			orderInfoReq.setUserId(0L);
		}
		List<OrderInfoRes> list = shopOrderService.userOrderList(orderInfoReq);
		Integer total = shopOrderService.userOrderListCount(orderInfoReq);
        PageUtils pageUtils = new PageUtils(list,total);
        return pageUtils;
	}
	
}
